#ifndef _MAIN_H_
#define	_MAIN_H_

#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <mysql/mysql.h>

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <termios.h>
#include <ctype.h>

#include <net/if.h>

#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sstream>
#include <errno.h>
#include <netinet/if_ether.h>


#include "debug.h"
#include "db.h"
#include "function.h"
#include "ppp4g.h"
#include "vpn.h"
#include "vlan.h"
#include "cmd_local.h"
#include "msdhAndUartHandle/uart_init.h"
#include "msdhAndUartHandle/if_unix.h"
#include "msdhAndUartHandle/global.h"
#include "msdhAndUartHandle/cmd.h"
#include "msdhSocketHandle/sock_pool.h"


// Ping test tools 
#include "lib_cloud.h"

//#define DEBUG_EN_SPEC_PRINT_FRAM


///#define PORT_START	10000
#define TCP			1
#define UDP			0
#define QINQ_TPID_8100	"8100"
#define QINQ_TPID_9100	"9100"
#define CREAT_CLIENT_CONF			0
#define CREAT_SERVER_CONF			1



//This is a flag to judge the Link break or not ;
const int DOWN = 0 ;
const int UP = 1 ;

// 4g start Mode ;
const int AUTO_ACTIVE_4G = 0 ;
const int ALWAYS_ONLINE = 1 ;
const int MANUAL_ACTIVE_4G = 2;

// VPN backup start Mode ;
const int AUTO_ACTIVE_VPN = 0 ;
const int MANUAL_ACTIVE_VPN = 1 ;

// Operator ;
const int UNICOM = 0 ;
const int TELECOM = 1 ;
const int MOBILE = 2;

//4Gppp APN set ;
const int APN_3GNET = 0 ;
const int APN_CTNET = 1 ;
const int APN_CMNET = 2 ;  

//
const int SECURITY_CHAP = 0 ;
const int SECURITY_PAP = 1 ;
const int SECURITY_NULL = 2 ;


//const int 
const int INT_MAX_VALUE = 2147483646 ;
const int SIZE_4096 = 4096 ;
const int SIZE_2048 = 2048 ;
const int SIZE_1024 = 1024 ;
const int SIZE_512 = 512 ;
const int SIZE_256 = 256 ;
const int SIZE_128 = 128 ;
const int SIZE_64  = 64 ;

const std::string PPP = "ppp0" ;
const std::string ETH4091 = "eth0.4091" ;

const std::string cloudServerCmd = "/root/trunk/lib/cloud_server" ;
const std::string cloudServerKillCmd = "killall cloud_server" ;

const std::string openvpnPath = "/etc/openvpn" ;

#define COM4G_MSG1 "/dev/msgsend"
#define COM4G_MSG2 "/dev/ttyUSB2"

/**/
#define	ACTION_AUTO		0
#define	ACTION_STATIC	1
#define	ACTION_PPPOE	2

#define NET_WORK_CONF_FILE		"/etc/network/interfaces"
#define STATIC_DNS_CONF_FILE	"/etc/resolvconf/resolv.conf.d/tail"
#define RESTART_THE_DNS_CONF	"service resolvconf restart "
#define RESTART_THE_NET_WORK	\
					"ifdown %s \n"\
					"ifup %s &\n"

#define WAN_IP_STATIC_SET		"ifconfig %s %s netmask %s \n"\
								"route del default \n"\
								"route add default gw %s dev %s \n"

#define PPPOE_DIAL_CONF_FILE		"/etc/ppp/peers/dsl-provider"
#define PPPOE_IDENTIFY_CONF_FILE	"/etc/ppp/chap-secrets"
#define PPPOE_DIAL_HANDLE			"pon dsl-provider"

#define INTERFACE_LAN_NAME				"eth0.4091"    //if interface_LAN name change ,please modify this macro definition

#define INTERFACE_WAN_NAME		"eth0.4091"      //if interface_wan name change,please modify this macro definition
#define CHECK_IF_PPPOE_FILE	"/tmp/check_if_pppoe_link.txt"

#define OPERATE_ERROR		1
#define OPERATE_SUCCESS		0


class G4Info {
public:
	int operator4g; //because ,operator is a key word in C++;
	int startMode;
	std::string apn4g;
	std::string username;
	std::string passwd;
	int securityMode;

/*	G4Info()
	{
		std::cout << "g4info construct function" << std::endl ;
	}

	~G4Info()
	{
		std::cout << "g4info destruct function" << std::endl ;
	}
*/
} ;

class vpnBase {
public:
	int serverOrNot;
	std::string vpnServerIp ;
	std::string linkBackInterface ;
	int backUpMode ;
	int proto ;
	int exchangeTime ;
	int detectFreq ; // Detect frequce,  unit is ms. Default is 500ms .
	int timesTamp ;
	int vpnPort;
	int ctoc ;

	vpnBase(){
		serverOrNot = 0 ;
		vpnServerIp = "" ;
		linkBackInterface = "eth0" ;
//		int backUpMode = 0 ;
//		int proto = UDP ;
		exchangeTime = 3 ;
		detectFreq = 500 ;
		timesTamp = 1 ;
		vpnPort = 1194 ;
		ctoc = 0;
	}

	~vpnBase()
	{
	//	std::cout << "Destruct vpnBase " << std::endl ;
	}
};

class vpnUserPass {
public:
	std::string username ;
	std::string passwd ;
};

class vpnPortFromVlan {
public:
	int port ;
	int vlanId ;
	int pid ;
};

class VlanIdFromS4P {
public:
	int vlanId ;
	std::string inface ;
	int qinqOrNot ;

	VlanIdFromS4P()
	{
		vlanId = 0 ;
		inface = "" ;
		qinqOrNot = 0 ;
	}

	~VlanIdFromS4P()
	{
	//	std::cout  << "destruct VlanIdFromS4P" << std::endl ;
	}
};

// Use vector<string> BackupInface replace this class ;
class VlanProtected
{
public:
	int vlanId ;
	std::string inface ;
	int qinqOrNot ;

	VlanProtected()
	{
		inface = "" ;
		vlanId = 0 ;
		qinqOrNot = 0 ;
	}

	~VlanProtected()
	{
	//	std::cout << "destruct " << std::endl;
	}
};

class DhcpConf 
{
public:
	int enable ;
	std::string lanIpAddr ;
	std::string dhcpStartIp;
	std::string dhcpEndIp ;
	std::string submask ;
	std::string gateway ;
	int leaseTime;
	std::string dnsAddr1 ;
	std::string dnsAddr2 ;
	
	DhcpConf()
	{
		enable = 0 ;
		lanIpAddr = "192.168.1.1" ;
		dhcpStartIp = "192.168.1.2" ;
		dhcpEndIp = "192.168.1.254";
		submask = "255.255.255.0" ;
		gateway = "192.168.1.1" ;
		leaseTime = 0 ;
		dnsAddr1 = "202.106.0.20";
		dnsAddr2 = "" ;
	}

	~DhcpConf()
	{
	//	std::cout << "destruct DhcpConf" << std::endl;
	}

};

class SystemConf
{
public:
	int cfgSave;
	int restore;
	std::string updateName ;
	std::string importName;
	std::string exportName;
	int updateAll;
	
	SystemConf()
	{
		cfgSave = 0 ;
		restore = 0;
		updateName = "" ;
		importName = "" ;
		exportName = "";
		updateAll = 0 ;
	
	}

	~SystemConf()
	{
	//	std::cout << "destruct SystemConf" << std::endl;
	}

};

class SwitchConf
{
public:
	int force_switch ;
	int soft_switch ;
};

class VlanModeInfo
{
public:
	int vlanMode;
	std::string vlanTPID;

	VlanModeInfo()
	{
		vlanMode = 0;
		vlanTPID = "8100";
	}
	~VlanModeInfo()
	{

	}
};


typedef struct userData
{
	unsigned char table_num;
	int vlan_id;
	unsigned short addr_pos;
	unsigned char vlan_id_for_snmp;
	int vlan_add_or_del;//0 is del,1 is add
	VPN_CONF_INFO table_C2_vpn_conf;
	
}USER_DATA;


typedef struct userType
{
	USER_DATA data;
	struct list_head list;			
	
}USER_TYPE;


// Define by Chen , A self define protocol in kernel.
#define ETH_P_CLOUD 0x8086 

/*
extern "C" {

//extern void get_config(char *dev_name,unsigned char op,unsigned char mode);
//extern int keep_alive(int swi,int time,char *dev_name);

extern int send_cloud(int sock,char *dev_name,unsigned char op,unsigned char mode,unsigned char type,void *p);
extern int recv_once_cloud(int sock);

}
*/

/*	main.cpp	*/
extern bool serverOrNot ;
extern G4Info g4 ;
extern vpnBase vpnServer ;
extern int uart_fd;
extern sock_pool *g_psock;//add by zzl
extern char QinqTpid[8];//add by zzl 20151126
extern int ConfRewTime ;
extern std::string proto ;
//extern H16MUP_4G01 g_entity;
extern DhcpConf dhcpConf;
extern int CtoCFlag ;
extern SwitchConf switchConf;
extern VlanModeInfo vlanModeInfo;//add by zzl 20160113
extern struct list_head *queue_head;
extern pthread_mutex_t mymutex; 
extern H16MUP_4G01 G401_conf;
extern struct dev_config dev_info;

extern const std::string pppUpCmd ;
extern const std::string pppDownCmd ;
extern const std::string pppAddGW ;
extern const std::string pppDelGwCmd  ;

extern std::vector<vpnUserPass> vpnUserPassVector ;
extern std::vector<vpnPortFromVlan> vpnPortFromVlanVector;
extern std::vector<VlanIdFromS4P> vlanIdFromS4pVector ;
extern std::vector<VlanProtected> VlanProtectedVector ;
extern std::vector<VlanProtected> VlanProtectedVectorCopy;

extern std::string openvpnCmd ;
extern std::string phoneNo ;
extern std::string wanInface ;

extern int BackUpState ;
extern int S4PHaveStartFlag ;
extern int NeedClearMacTableFlag ;

extern std::string createVpnServerCmd(std::string fileName) ;

#endif
